/*
 * Filename PatientMapping.java 2021年09月29日
 * Copyright © Ehome Co.Ltd. All Rgiths Reserved.
 * @author wuyingchao
 */
package com.ehome.poct.core.dao.mapping;

import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;
import com.ehome.poct.core.api.dto.report.DiseaseQryDTO;
import com.ehome.poct.core.api.dto.TestDataDTO;
import com.ehome.poct.core.api.dto.check.CellCheckDataDTO;
import com.ehome.poct.core.api.dto.check.CheckItemIndicatorDTO;
import com.ehome.poct.core.api.dto.check.CheckProjectDTO;
import com.ehome.poct.core.api.dto.check.CheckReportDTO;
import com.ehome.poct.core.api.dto.check.gold.*;
import com.ehome.poct.core.api.dto.order.TestOrderDTO;
import com.ehome.poct.core.api.dto.report.TestConfUniProjectDescDTO;
import com.ehome.poct.core.api.vo.*;
import com.ehome.poct.core.api.vo.patient.PatientDetailVO;
import com.ehome.poct.core.api.vo.report.DiseaseCategoryVO;
import com.ehome.poct.core.dao.entity.check.*;
import com.ehome.poct.core.dao.entity.order.TestOrderDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;

import java.math.BigDecimal;
import java.util.List;

/**
 * 报告 mapping
 *
 * @author muqiu
 * @since 2022/03/04 14:54
 **/
@Mapper(componentModel = "spring", imports = {JSONUtil.class, CheckChartDataVO.class, ResultImgVO.class, CheckResultVO.class, BigDecimal.class, Convert.class})
public interface CheckReportMapping {

    List<CheckReportVO> toReportListVO(List<TestReportPoctDO> entitys);

    @Mapping(target = "reportName", source = "name")
    @Mapping(target = "bloodCheckReportId", source = "testReportPoctId")
    @Mapping(target = "orderNo", source = "payOrderNo")
    CheckReportVO to(TestReportPoctDO entity);

    @Mapping(target = "reqId", expression = "java(data.getAlgoReqId().toString())")
    @Mapping(target = "path", expression = "java(data.getOssFileId().replaceAll(\".zip\", \"\"))")
    @Mapping(target = "testTime", source = "data.createTime")
    @Mapping(target = "payOrderNo", source = "report.orderNo")
    @Mapping(target = "projectDesc", source = "project.projectDesc")
    @Mapping(target = "reportName", source = "project.checkProjectName")
    @Mapping(target = "chart", expression = "java(JSONUtil.toList(data.getCheckResultChatData(), CheckChartDataVO.class))")
    @Mapping(target = "images", expression = "java(JSONUtil.toList(data.getCheckResultImgs(), ResultImgVO.class))")
    @Mapping(target = "results", expression = "java(JSONUtil.toList(data.getCheckResult(), CheckResultVO.class))")
    ReportDetailVO toVO(CheckReportDO report, CheckDataDO data, PatientDetailVO patient, CheckProjectDO project, TestOrderDO order);

    @Mapping(target = "rrs", source = "kpi.reference")
    @Mapping(target = "type", source = "simpleName")
    @Mapping(target = "value", expression = "java(adornValue(Convert.toBigDecimal(result.getValue(), BigDecimal.ZERO), kpi))")
    CheckResultVO to(@MappingTarget CheckResultVO result, CheckItemIndicatorDO kpi);

    @Mapping(target = "rrs", source = "kpi.reference")
    @Mapping(target = "type", source = "simpleName")
    @Mapping(target = "value", expression = "java(adornValue(Convert.toBigDecimal(result.getValue(), BigDecimal.ZERO), kpi))")
    CheckResultVO toCheckResultVO(@MappingTarget CheckResultVO result, CheckItemIndicatorDTO kpi);


    @Mapping(target = "typeName", source = "stripType.fullName")
    @Mapping(target = "type", source = "stripMapping.stripMapName")
//    @Mapping(target = "rrs", expression = "java(userType.equals(1) ? stripType.getChildReference() : stripType.getStandardReference())")
    @Mapping(target = "unit", source = "stripType.unit")
    @Mapping(target = "value", expression = "java(translateTestValue(stripType.getTypeCode(), data.getValue1(), stripMapping.getMax(), stripMapping.getMin(), rrs))")
    @Mapping(target = "stripTypeCode",source = "stripType.typeCode")
    CheckResultVO to(TestDataDetailDO data, TestConfPoctStripTypeDO stripType, TestConfPoctStripMappingDO stripMapping, TestConfPoctAnalysisDO analysis, String rrs);

    @Mapping(target = "typeName", source = "stripType.fullName")
    @Mapping(target = "type", source = "stripMapping.stripMapName")
//    @Mapping(target = "rrs", expression = "java(userType.equals(1) ? stripType.getChildReference() : stripType.getStandardReference())")
    @Mapping(target = "unit", source = "stripType.unit")
    @Mapping(target = "value", expression = "java(translateTestValue(stripType.getTypeCode(), data.getValue1(), stripMapping.getMax(), stripMapping.getMin(), rrs))")
    @Mapping(target = "stripTypeCode",source = "stripType.typeCode")
    CheckResultVO toResult(TestDataDetailDTO data, TestConfPoctStripTypeDTO stripType, TestConfPoctStripMappingDTO stripMapping, TestConfPoctAnalysisDTO analysis, String rrs);

    @Mapping(target = "valueA", source = "analysisResultA")
    @Mapping(target = "valueB", source = "analysisResultB")
    @Mapping(target = "timeFlag", constant = "5")
    DiseaseQryDTO to(TestReportPoctUniDO report);

    @Mapping(target = "valueA", source = "analysisResultA")
    @Mapping(target = "valueB", source = "analysisResultB")
    @Mapping(target = "timeFlag", constant = "5")
    DiseaseQryDTO toDiseaseQryDTO(TestReportPoctUniDTO report);

    @Mapping(target = "reqId", source = "data.reqId")
    @Mapping(target = "path", expression = "java(data.getFilePath().replaceAll(\".zip\", \"\"))")
    @Mapping(target = "testTime", source = "data.checkTime")
    @Mapping(target = "payOrderNo", source = "report.orderNo")
    @Mapping(target = "projectDesc", source = "project.projectDesc")
    @Mapping(target = "reportName", source = "project.checkProjectName")
    @Mapping(target = "chart", expression = "java(JSONUtil.toList(data.getChart(), CheckChartDataVO.class))")
    @Mapping(target = "images", expression = "java(JSONUtil.toList(data.getCheckResultImgs(), ResultImgVO.class))")
    @Mapping(target = "results", expression = "java(JSONUtil.toList(data.getResult(), CheckResultVO.class))")
    ReportDetailVO toDetail(CheckReportDTO report, CellCheckDataDTO data, PatientDetailVO patient, CheckProjectDTO project, TestOrderDTO order);

    List<DiseaseCategoryVO> to(List<DiseaseCategoryVO> dto);

    List<DiseaseCategoryVO> toDiseaseCategoryList(List<DiseaseCategoryVO> dto);

    List<StripKpisVO> toKpis(List<TestConfPoctAnalysisDO> kpis);

    @Mapping(target = "stripName", expression = "java(testData.getStripMapping().getStripMapName() + ' ' + testData.getStripType().getFullName())")
    @Mapping(target = "stripDesc", source = "testData.stripType.description")
    @Mapping(target = "stripType", source = "testData.stripType.type")
    @Mapping(target = "orderNo", source = "report.payOrderNo")
    @Mapping(target = "analysis", expression = "java(getAnalysisContent(testData, report.getAnalyseId()))")
    @Mapping(target = "clinicalAnalyseLevel",source = "report.clinicalAnalyseLevel")
    @Mapping(target = "sampleType",source = "testData.stripType.sampleType")
    @Mapping(target = "createTime",source = "report.createTime")
    ReportDtlVO toReportDtlVO(TestReportPoctDTO report, PatientDetailVO patient, TestDataDTO testData, String wxAuthUrl);

    @Mapping(target = "confPoctAnalysisId", source = "testConfPoctUnionAnalysisId")
    @Mapping(target = "result", expression = "java(union.getStripTypeAResult() + '/' + union.getStripTypeBResult())")
    TestConfPoctAnalysisDTO to(TestConfPoctUniAnalysisDO union);

    /**
     * 获取检测分析
     *
     * @param data 检测数据
     * @param id   联合检测配置id
     * @return 检测分析
     */
    default String getAnalysisContent(TestDataDTO data, Long id) {
        if (data.isMultiValue()) {
            return new TestConfPoctUniAnalysisDO().selectById(id).getUniAnalysis();
        }
        return new TestConfPoctAnalysisDO().selectById(id).getContent();
    }


    /**
     * 装饰检测值
     *
     * @param value 检测值组装
     * @param kpi   检测指标
     * @return
     */
    default String adornValue(BigDecimal value, CheckItemIndicatorDTO kpi) {
        if (kpi != null) {
            if (value.compareTo(kpi.getMaxValue()) > 0) {
                return value + " ↑";
            } else if (value.compareTo(kpi.getMinValue()) < 0) {
                return value + " ↓";
            }
        }
        return value.toString();
    }

    /**
     * 装饰检测值
     *
     * @param value 检测值组装
     * @param kpi   检测指标
     * @return
     */
    default String adornValue(BigDecimal value, CheckItemIndicatorDO kpi) {
        if (kpi != null) {
            if (value.compareTo(kpi.getMaxValue()) > 0) {
                return value + " ↑";
            } else if (value.compareTo(kpi.getMinValue()) < 0) {
                return value + " ↓";
            }
        }
        return value.toString();
    }

    /**
     * @param strip
     * @param value
     * @param max
     * @param min
     * @return
     */
    default String translateTestValue(Integer strip, BigDecimal value, BigDecimal max, BigDecimal min, String rrs) {
        final var rrsArray = rrs.split("~");
        final var minRRS = new BigDecimal(rrsArray[0]);
        final var maxRRS = new BigDecimal(rrsArray[1]);
        var tag = "";
        if (value.compareTo(minRRS) < 0) {
            tag = " ↓";
        } else if (value.compareTo(maxRRS) > 0) {
            tag = " ↑";
        }

        // CRP检测
        if (strip.equals(4)) {
            if (value.compareTo(BigDecimal.valueOf(10)) >= 0) {
                if (value.compareTo(max) >= 0) {
                    return "常规:≥" + max + tag + "\n超敏:≥10.00";
                } else {
                    return "常规:" + value + tag + "\n超敏:≥10.00";
                }
            } else {
                return "常规:<10.00\n超敏:" + value + tag;
            }
        }
        // 其他检测
        else {
            if (value.compareTo(max) >= 0) {
                return "≥" + max + tag;
            } else if (value.compareTo(min) <= 0) {
                return "≤" + min + tag;
            }
        }
        return value + tag;
    }

    @Mapping(target = "stripType", source = "report.uniAnalyseType")
    @Mapping(target = "orderNo", source = "report.payOrderNo")
    @Mapping(target = "analysis", expression = "java(getUniAnalysisContent(report.getUniAnalyseId()))")
    @Mapping(target = "stripDesc", source = "projectDesc.description")
    @Mapping(target = "clinicalAnalyseLevel",source = "report.clinicalAnalyseLevel")
    @Mapping(target = "createTime",source = "report.createTime")
    ReportDtlVO to(TestReportPoctUniDTO report, String stripName, PatientDetailVO patient, String wxAuthUrl, TestConfUniProjectDescDTO projectDesc, String sampleType);

    default String getUniAnalysisContent(Long id) {
        return new TestConfPoctUniAnalysisDO().selectById(id).getUniAnalysis();
    }
}